package com.econ.powercloud.ems.common.util;

import org.joda.time.DateTime;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateTimeUtil {

    public static final DateTimeFormatter DEFAULT_DATETIME_FORMATE = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DEFAULT_DATE_FORMATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public static final ZoneOffset SYSTEM_ZONE_OFFSET = ZoneOffset.of("+8");
    public static final ZoneId SYSTEM_ZONE_ID = ZoneId.of("+8");

    public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
    public static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String HOUR_PATTERN = "HH时";
    public static final String DAY_PATTERN = "dd日";
    public static final String MONTH_PATTERN = "MM月";

    public static String formatEpoclSecond(Integer epochSecond, String pattern) {
        return LocalDateTime.ofEpochSecond(epochSecond, 0, SYSTEM_ZONE_OFFSET)
                .format(DateTimeFormatter.ofPattern(pattern));
    }

    public static long getLongUninTimestamp00h00m00sByDate(Date date){
        Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(SYSTEM_ZONE_ID));
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        long longUninTimestamp = calendar.getTime().getTime();
        return longUninTimestamp;
    }

    /**
     *
     * @param date
     * @param pattern e.g. "yyyy-MM-dd HH:mm:ss"
     * @return
     */
    public static String formatDate(Date date, String pattern){
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    public static String formatEpoclSecond(Long epochSecond, String pattern) {
        return LocalDateTime.ofEpochSecond(epochSecond, 0, SYSTEM_ZONE_OFFSET)
                .format(DateTimeFormatter.ofPattern(pattern));
    }

    public static LocalDateTime ofEpoclSecond(Integer epochSecond) {
        return LocalDateTime.ofEpochSecond(epochSecond, 0, SYSTEM_ZONE_OFFSET);
    }

    public static Integer toEpoclSecond(LocalDateTime localDateTime) {
        return Long.valueOf(localDateTime.toEpochSecond(SYSTEM_ZONE_OFFSET)).intValue();
    }

    public static LocalDateTime defaultSysDateTime() {
        return LocalDateTime.now(SYSTEM_ZONE_ID);
    }

    public static Integer defaultSysDateTimeSec() {
        return toEpoclSecond(defaultSysDateTime());
    }

    public static Date getExpirationDate(String expirationSecond) {
        return getExpirationDate(defaultSysDateTime(), expirationSecond);
    }

    public static Date getExpirationDate(LocalDateTime startDateTime, String expirationSecond) {
        return Date.from(startDateTime.plusSeconds(Long.valueOf(expirationSecond)).toInstant(SYSTEM_ZONE_OFFSET));
    }

    public static Date getExpirationDatePlusDays(String expirationDays) {
        return Date.from(defaultSysDateTime().plusDays(Long.valueOf(expirationDays)).toInstant(SYSTEM_ZONE_OFFSET));
    }

    public static LocalDateTime ofDate(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), SYSTEM_ZONE_ID);
    }

    public static Integer ofDateToEpoclSecond(Date date) {
        return toEpoclSecond(ofDate(date));
    }

    public static String formatDateTime(LocalDateTime localDateTime, String pattern) {
        return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static Integer getCurrentTimestampBySec() {
        String currentTimeMillis = String.valueOf(System.currentTimeMillis());

        return Integer.valueOf(currentTimeMillis.substring(0, currentTimeMillis.length() - 3));
    }

    /**
     * 名字想不到怎么起了，大概做的工作是：
     * 根据一个时间戳，获取那一天的晚上11点59分59秒的时间戳
     */
    public static Integer get23h59m59s(Integer timestampSec) {
        LocalDateTime localDateTime = ofEpoclSecond(timestampSec);
        int year = localDateTime.getYear();
        Month month = localDateTime.getMonth();
        int dayOfMonth = localDateTime.getDayOfMonth();
        LocalDateTime dateTime = LocalDateTime.of(year, month, dayOfMonth, 23, 59, 59);
        return toEpoclSecond(dateTime);
    }

    /**
     * 就是获取今天晚上11点59分59秒的时间戳
     */
    public static Integer getToday23h59m59s() {
        return get23h59m59s(defaultSysDateTimeSec());
    }

    /**
     * 获取 系统日期的时间零时零分零秒 的时间戳)
     */
    public static Integer getToday00h00m00s() {
        return toEpoclSecond(defaultSysDateTime().withHour(0).withMinute(0).withSecond(0));
    }
    /**
     * 获取 某天的开始时间
     */
    public static Long getStartOfDay(Date date){
        if (date == null) {
            date = new Date();
        }
        DateTime dateTime = new DateTime(date).secondOfDay().withMinimumValue().millisOfDay().withMinimumValue();
        return dateTime.toDate().getTime();
    }

    /**
     * 获取 某天的结束时间
     */
    public static Long getEndOfDay(Date date){
        if (date == null) {
            date = new Date();
        }
        DateTime dateTime = new DateTime(date).secondOfDay().withMaximumValue().millisOfDay().withMaximumValue();
        return dateTime.toDate().getTime();
    }

    /**
     * 取前一天时间
     *
     * @param date
     * @return
     */
    public static Date getBeforeDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        date = calendar.getTime();
        return date;
    }
    /**
     * 获取 当前时间的上一个小时的开始时间
     * 1583334000000 -> 2020-03-04 23:00:00
     */
    public static Long getStartOfLastHour(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int h = cal.get(Calendar.HOUR_OF_DAY);
        cal.set(Calendar.HOUR_OF_DAY,cal.get(Calendar.HOUR_OF_DAY)-1);
        cal.set(Calendar.MINUTE,cal.getMinimum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMinimum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMinimum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }
    /**
     * 获取 当前时间的上一个小时的结束时间
     * 例如:1583337599999 ->2020-03-04 23:59:59
     */
    public static Long getEndOfLastHour(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int h = cal.get(Calendar.HOUR_OF_DAY);
        cal.set(Calendar.HOUR_OF_DAY,cal.get(Calendar.HOUR_OF_DAY)-1);
        cal.set(Calendar.MINUTE,cal.getMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMaximum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }
    /**
     * 获取 当前时间的上一个小时的整点时间
     * 例如:1583337599999 ->2020-03-04 23:59:59
     */
    public static String getHourOfTime(Long time){
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date(time));
        int h = cal.get(Calendar.HOUR_OF_DAY);
        return String.format("%02d",h);
    }
    /**
     * 获取date日期月的开始时间
     *
     */
    public static Long getStartOfMonth(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH,cal.getMinimum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY,cal.getMinimum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE,cal.getMinimum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMinimum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMinimum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }
    /**
     * 获取date日期月的结束时间
     *
     */
    public static Long getEndOfMonth(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH,cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY,cal.getMaximum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE,cal.getMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMaximum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }

    /**
     * 获取date日期年的开始时间
     *
     */
    public static Long getStartOfYear(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH,cal.getMinimum(Calendar.MONTH));
        cal.set(Calendar.DAY_OF_MONTH,cal.getMinimum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY,cal.getMinimum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE,cal.getMinimum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMinimum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMinimum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }
    /**
     * 获取date日期年的结束时间
     *
     */
    public static Long getEndOfYear(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH,cal.getMaximum(Calendar.MONTH));
        cal.set(Calendar.DAY_OF_MONTH,cal.getMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY,cal.getMaximum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE,cal.getMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMaximum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }
    /**
     * 获取date日期Long型年月
     *
     */
    public static Long getYearMonthByDate(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH)+1;
        String yearMonth = String.valueOf(year) + String.format("%02d",month);
        return Long.valueOf(yearMonth);
    }
    /**
     * 获取date日期Long型年
     *
     */
    public static Long getYearByDate(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int year = cal.get(Calendar.YEAR);
        return Long.valueOf(year);
    }

    public static void main(String[] args) { Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH,calendar.get(Calendar.MONTH)-3);
        long startTime = DateTimeUtil.getStartOfMonth(calendar.getTime());
        System.out.println(startTime);
    }

    /**
     * 获取 当前时间对应的小时开始时间
     */
    public static Long getStartOfHour(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int h = cal.get(Calendar.HOUR_OF_DAY);
        cal.set(Calendar.HOUR_OF_DAY,cal.get(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE,cal.getMinimum(Calendar.MINUTE));
        cal.set(Calendar.SECOND,cal.getMinimum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND,cal.getMinimum(Calendar.MILLISECOND));
        DateTime dateTime = new DateTime(cal.getTime());
        return dateTime.toDate().getTime();
    }

}
